<?

require_once('Gpc/User/Adapter/Abstract.php');

class Gpc_User_Adapter_Phpbb3 extends Gpc_User_Adapter_Abstract {

  /*
   * Maps phpBB3 column names to GPC Raids column names
   * 
   * phpbb3 => gpc_raids
   * Mininum columns required: id, username, email
   */
  protected $identityMap = array( 'user_id' => 'id', 
                                  'username_clean' => 'username', 
                                  'user_email' => 'email');

  /*
   * Stores the phpBB3 globals required by this class 
   */
  protected $phpbbVar = array();

  public function __construct() {
    parent::__construct();
    $this->tableName = $this->tablePrefix . $this->tableName;

    // Tell phpBB we're using it
    define('IN_PHPBB', true);
    define('PHPBB_ROOT_PATH', WWW_ROOT . DS . $this->forumPath);
  }

  /**
   * Authentications the user.
   *
   * phpBB3 Authentication method is unique. We have to overwrite
   * the global authentication method to compensate
   */
  public function authenticate( $username, $password ) {
    /* 
     * This seems to work. Can't find anything broken. 
     * Logs me in just fine to my site and the forums.
     *
     * Pulled from includes/functions.php line 2247 
     */
    $result = $this->phpbbVar['auth']->login($username, $password);  // TODO: Add presistance flag
    
    switch ( $result['status'] ) {
      case LOGIN_SUCCESS:
        $zendAuthResult = Zend_Auth_Result::SUCCESS;
        break;
      case LOGIN_ERROR_USERNAME: 
        $zendAuthResult = Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND;
        break;
      case LOGIN_ERROR_PASSWORD:
        $zendAuthResult = Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID;
        break;
      default: 
        $zendAuthResult = Zend_Auth_Result::FAILURE;
        break;
    }

    /* TODO: Add some kind of translator here to translate results to Zend_Auth_Result */
    /* Return a Zend_Auth_Result class since that's what the code expects */
    return new Zend_Auth_Result($zendAuthResult, $result['user_row']['username']);
  }

  /**
   * Loads up the user's session based on phpBB3's session handers.
   */
  public function loadUserSession() {
    /* Bleh, phpBB and their bloody global variables */
    global $db, $acl, $user, $auth, $template, $cache, $phpEx, 
           $phpbb_root_path, $SID, $_SID, $_EXTRA_URL, $config;

    $phpbb_root_path = PHPBB_ROOT_PATH;
    $phpEx = substr(strrchr(__FILE__, '.'), 1);

    include_once($phpbb_root_path . 'common.' . $phpEx);

    /* Gonna store them locally. */
    $this->phpbbVar['user'] = new user();
    $this->phpbbVar['auth'] = new auth();
    
    
    $this->phpbbVar['user'] = $user;
    $this->phpbbVar['acl']  = $acl;
    $this->phpbbVar['auth']  = $auth;

    /*
     * phpBB3 handles it's own session management, including its own cookies which
     * are based on random keys. So, let phpBB3 everything for me 
     */
    $this->phpbbVar['user']->session_begin();
    $this->phpbbVar['auth']->acl($this->phpbbVar['user']->data);
    
    if ( $this->phpbbVar['user']->data['user_id'] != ANONYMOUS ) {
      $this->_translateIdentity($this->phpbbVar['user']->data);
    } else {
      /* phpBB3 says they are anonymous - clear your Zend identity */
      Zend_Auth::getInstance()->clearIdentity();
    }
  }

  /**
   * Logs the user out.
   *
   * Logs the user out of phpBB3 first then calls the parent method
   * to log them out of the Zend Framework 
   */
  public function logout() {
    $this->phpbbVar['user']->session_kill();
    $this->phpbbVar['user']->session_begin();
    parent::logout();
  }

  protected function _setPassword( $password ) {
    /* 
     * This isn't going to work -- the salt for the hash is contained in the hashed password.
     * There is no way to hash the password to compare it 1:1 to the password in the db without
     *   first pulling it from the db.
     */

    /* Pulled from phpbb_check_hash() in includes/functions.php 
    $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    $this->password = _hash_crypt_private($password, $hash, $itoa64) === $hash) ? true : false;
    */ 
  }
}
